#pragma once

#include <iostream>
#include <string>
#include <regex>
#include <unordered_map>

class HttpRequest
{
public:
    std::string _method;  // 请求方法
    std::string _path;    // 请求路径
    std::string _version; // 协议版本
    std::string _body;    // 请求正文
    std::smatch _matches; // 资源路径的正则提取数据

    std::unordered_map<std::string, std::string> _headers; // 头部字段
    std::unordered_map<std::string, std::string> _params;  // 查询字符串

public:
    HttpRequest() :_version("HTTP/1.1") {}
    //重新设置
    void Reset()
    {
        _method.clear();
        _path.clear();
        _version = "HTTP/1.1";
        _body.clear();
        std::smatch matches;
        matches.swap(_matches);
        _headers.clear();
        _params.clear();
    }

    //插入头部字段
    void SetHeader(const std::string &key, const std::string &val)
    {
        _headers.insert(std::make_pair(key, val));
    }
    //判断是否存在指定的头部字段
    bool HasHeader(const std::string &key) const
    {
        auto it = _headers.find(key);
        if(it == _headers.end())
            return false;
        return true;
    }
    //获取指定的头部字段的值
    std::string GetHeader(const std::string &key) const
    {
        auto it = _headers.find(key);
        if(it == _headers.end())
            return "";
        return it->second;
    }

    //插入查询字符串
    void SetParam(const std::string &key, const std::string &val)
    {
        _params.insert(std::make_pair(key, val));
    }
    //判断是否有指定的查询字符串
    bool HasParam(const std::string &key) const
    {
        auto it = _params.find(key);
        if(it == _params.end())
            return false;
        return true;
    }
    //获取指定的查询字符串
    std::string GetParam(const std::string &key) const
    {
        auto it = _params.find(key);
        if(it == _params.end())
            return "";
        return it->second;
    }

    //获取正文长度
    size_t ContentLength() const
    {
        bool ret = HasHeader("Content-Length");
        if(ret == false)
            return 0;
        std::string length = GetHeader("Content-Length");
        return std::stoi(length);
    }

    //判断是否是短连接
    bool Close() const
    {
        if(HasHeader("Connection") == true && GetHeader("Connection") == "keep-alive")
            return false;
        return true;
    }
};